﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Sockets;
using System.Net;

namespace WpfWordsLearner.DesktopSharer
{
	public sealed class Sender
	{
		private IPEndPoint ipEndPoint;
		private UdpClient udpClient;
		private int width;
		private int height;
		private Stopper st = null;

		public Sender()
		{
			st = new Stopper();
		}

		public void Run()
		{
			Load();

			udpClient = new UdpClient();
			System.Drawing.Bitmap BackGround = new System.Drawing.Bitmap(width, height);
			System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(BackGround);

			while (true)
			{
				if (st.IsStopReguested)
					break;

				graphics.CopyFromScreen(0, 0, 0, 0, new System.Drawing.Size(width, height));   // Get snapshot of screen
				byte[] bytes = ConvertToByte(BackGround);                      // Get image in byte representation
				List<byte[]> lst = CutMsg(bytes);
				for (int i = 0; i < lst.Count; i++)
				{
					udpClient.Send(lst[i], lst[i].Length, ipEndPoint);                // send picture to the client
				}
			}
		}

		public void Stop()
		{
			if (!st.IsStopReguested)
				st.RequestStop();
		}

		// Load data
		private void Load()
		{
			// Load Ip address and port
			using (StreamReader streamReader = new StreamReader("ip.txt"))
			{
				string ip = streamReader.ReadLine();
				int port = Convert.ToInt32(streamReader.ReadLine());

				ipEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
			}

			width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
			height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
		}

		// Convert image in bytes array whith JPEG conmpression
		private byte[] ConvertToByte(System.Drawing.Bitmap bmp)
		{
			MemoryStream memoryStream = new MemoryStream();
			bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
			return memoryStream.ToArray();
		}

		private List<byte[]> CutMsg(byte[] bt)
		{
			int Lenght = bt.Length;
			byte[] temp;
			List<byte[]> msg = new List<byte[]>();

			MemoryStream memoryStream = new MemoryStream();
			memoryStream.Write(BitConverter.GetBytes((short)((Lenght / 65500) + 1)), 0, 2);
			memoryStream.Write(bt, 0, bt.Length);
			memoryStream.Position = 0;
			while (Lenght > 0)
			{
				temp = new byte[65500];
				memoryStream.Read(temp, 0, 65500);
				msg.Add(temp);
				Lenght -= 65500;
			}

			return msg;
		}
	}

	internal sealed class Stopper
	{
		private volatile static bool m_requestStop = false;

		public Stopper() { }

		public bool IsStopReguested
		{
			get { return m_requestStop; }
		}

		public void RequestStop()
		{
			m_requestStop = true;
		}
	}
}